package com.abc.server;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Set;
import java.util.TreeMap;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.abc.client.GreetingService;
import com.abc.shared.Classification;
import com.abc.shared.ClassifiedItem;
import com.abc.shared.FieldVerifier;
import com.google.gwt.user.server.rpc.RemoteServiceServlet;

/**
 * The server side implementation of the RPC service.
 */
@SuppressWarnings("serial")
public class GreetingServiceImpl extends RemoteServiceServlet implements
		GreetingService {

	private DatabaseConnection DatabaseCon=null;
		
	public String greetServer(String input) throws IllegalArgumentException {
		// Verify that the input is valid. 
		if (!FieldVerifier.isValidName(input)) {
			// If the input is not valid, throw an IllegalArgumentException back to
			// the client.
			throw new IllegalArgumentException(
					"Name must be at least 4 characters long");
		}

		String serverInfo = getServletContext().getServerInfo();
		String userAgent = getThreadLocalRequest().getHeader("User-Agent");

		// Escape data from the client to avoid cross-site script vulnerabilities.
		input = escapeHtml(input);
		userAgent = escapeHtml(userAgent);

		return "Hello, " + input + "!<br><br>I am running " + serverInfo
				+ ".<br><br>It looks like you are using:<br>" + userAgent;
	}

	/**
	 * Escape an html string. Escaping data received from the client helps to
	 * prevent cross-site script vulnerabilities.
	 * 
	 * @param html the html string to escape
	 * @return the escaped string
	 */
	private String escapeHtml(String html) {
		if (html == null) {
			return null;
		}
		return html.replaceAll("&", "&amp;").replaceAll("<", "&lt;")
				.replaceAll(">", "&gt;");
	}

	@Override
	public Classification getClassification() {
		// TODO Auto-generated method stub
		Classification<Classification> classification = new Classification<Classification>(0,"Classification");
			
		classificationIttorator(classification, 0);
		
		return classification;
	}
	
	
	private void classificationIttorator (Classification classific, int parent){
		
		try {
			if(DatabaseCon==null)
				DatabaseCon= new DatabaseConnection(null);
		
			LinkedHashMap<Integer, String> children = DatabaseCon.getClassifiedItemByParent(parent);			
			Set<Integer> Keys= children.keySet();
				
			
			
			for (Integer key: Keys) {					
				
				Classification<Classification> newclassi = new Classification<Classification>(key, (String)children.get(key));
				classific.add(newclassi);	
				System.out.println("Name:"+newclassi.getName());
				
				classificationIttorator(newclassi, key);
									
			}
				
					
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}		
		
	}

	

	
	@Override
	public ClassifiedItem getClassifiedItem(int itemid) {

		try {
			if(DatabaseCon==null)
				DatabaseCon= new DatabaseConnection(null);
		
			ClassifiedItem classi = DatabaseCon.getClassifiedItemByID(itemid);			
			
				return classi;
					
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}		
		
		return null;
	}

	@Override
	public ClassifiedItem updateItem(ClassifiedItem item) {
		
		try {
			if(DatabaseCon==null)
				DatabaseCon= new DatabaseConnection(null);
		
			DatabaseCon.sqlUpdate("UPDATE `classification` SET `parentid`="+item.getParentID()+",`name`='"+item.getName()+"',`prompt`='"+item.getPrompt()+"',`rank`="+item.getRank()+",`smstext`='"+item.getSmsText()+"',`keywords`='"+item.getKeywords()+"',`servicetype`='"+item.getServiceType()+"',`level`="+item.getLevel()+",`lngtude_maxprice`="+item.getLngtdeMaxprize()+",`lattude_minprice`="+item.getLttudeMinprize()+" WHERE `itemid`="+item.getItemID()); 
					
			return DatabaseCon.getClassifiedItemByID(item.getItemID());
					
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}		
		
		return null;
	}

	@Override
	public ClassifiedItem addItem(ClassifiedItem item) {
		try {
			if(DatabaseCon==null)
				DatabaseCon= new DatabaseConnection(null);
		
			DatabaseCon.sqlUpdate("INSERT INTO `classification`(`itemid`, `parentid`, `name`, `prompt`, `rank`, `smstext`, `keywords`, `servicetype`, `level`, `lngtude_maxprice`, `lattude_minprice`) " +"VALUES (null,"+item.getParentID()+",'"+item.getName()+"','"+item.getPrompt()+"',"+item.getRank()+",'"+item.getSmsText()+"','"+item.getKeywords()+"','"+item.getServiceType()+"',"+item.getLevel()+","+item.getLngtdeMaxprize()+","+item.getLttudeMinprize()+")"); 
			
			ResultSet results = DatabaseCon.sqlSelect("SELECT * FROM `classification` order by itemid desc limit 1");
		     
		    results.next();
		    return new ClassifiedItem(results.getInt("itemid"), results.getInt("parentid"), results.getString("name"), results.getString("prompt"), results.getInt("rank"), results.getString("keywords"), results.getString("servicetype"), results.getInt("level"),results.getString("smstext"), results.getDouble("lngtude_maxprice"),results.getDouble("lattude_minprice"));
		   		    					
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}		
		
		return null;
	}

	@Override
	public Boolean deleteBranch(int itemid) {
		try {
			if(DatabaseCon==null)
				DatabaseCon= new DatabaseConnection(null);
		
			LinkedHashMap<Integer, String> children = DatabaseCon.getClassifiedItemByParent(itemid);			
			Set<Integer> Keys= children.keySet();
			for (Integer key: Keys) {	
								
				deleteBranch(key);
									
			}
				
			DatabaseCon.deleteClassifiedItemByID(itemid);
					
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}		
		return true;
	}

	@Override
	public Boolean updateParent(int newparent, int itemid) {
		try {
			if(DatabaseCon==null)
				DatabaseCon= new DatabaseConnection(null);
		
			DatabaseCon.sqlUpdate("update  `classification` set `parentid`="+newparent+" where `itemid`="+itemid); 
							
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}		
		
		return null;
	}
	
	
}
